package actions.threads;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import actions.runnable.SubmitJob;

import objects.MessageCodes;
import objects.ObjectCodes;
import objects.data.Message;
import objects.data.WorkPacket;

import ssh.SSHUtils;


import data.WebSocket;

import utils.Utils;

public class ReceiveThread extends Thread implements ObjectCodes {
	public static volatile boolean run = true;
	private WebSocket ws;
	private String username;

	public ReceiveThread() {
		this.ws = Utils.ws;
		this.username = Utils.username;
	}

	public void run() {
		while (run) {
			try {
				String data = ws.recv();

				String[] tokens = data.split("\\|");

				byte obj_type = Byte.parseByte(tokens[0]);
				String json = tokens[1];

				if (obj_type == PING) {
					Utils.ws.send("8|0");
					continue;
				}
				// Utils.out("RECV: " + data);
				switch (obj_type) {
				case CLI_WORK_PKT: {
					HandleJobSubmission(json);
					break;
				}
				case MSG: {
					HandleMessage(json);
					break;
				}
				}
			} catch (IOException e) {
				System.out.println(e.getMessage());
				run = false;
			}

		}

	}

	private void HandleJobSubmission(String json) {
		WorkPacket wp = WorkPacket.fromJSon(json);
		Utils.out("+ received job submission request: " + json);
		Utils.out("+ starting job submit thread");
		Utils.exec.execute(new SubmitJob(wp));
	}

	private void HandleMessage(String json) throws IOException {
		Message msg = Message.fromJson(json);
		if (msg.type == MessageCodes.CANCEL_JOB) {
			final String jobId = msg.msg;
			if (!Utils.jobs.containsKey(jobId)) {
				Utils.ws.send(new Message(MessageCodes.ERR,
						"Too early or to late to cancel job!"));
			} else {
				Utils.exec.execute(new Runnable() {
					public void run() {
						try {
							Runtime run = Runtime.getRuntime();
							Process p = run.exec("qdel "
									+ Utils.jobs.get(jobId).jobid);
							int success = p.waitFor();
							if (success == 0)
								Utils.ws.send(new Message(MessageCodes.OK,
										"Job canceled"));
							else
								Utils.ws.send(new Message(MessageCodes.ERR,
										"Too early or to late to cancel job!"));
						} catch (Exception e) {
						}
					}

				});

			}
		}
	}

	class Cmd implements Runnable {
		String cmd;
		String id;

		public Cmd(String c, String id) {
			this.cmd = c;
			this.id = id;
		}

		public void run() {
			try {
				Process child = Runtime.getRuntime().exec(cmd);
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(child.getInputStream()));
				String s = "";
				String line;
				while ((line = reader.readLine()) != null) {
					System.out.println("Stdout: " + line);
					s += line;
				}
				int exitstatus = child.waitFor();
				ws.send("msg|cmd|" + id + "|" + exitstatus + "|" + s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
